using ComputeSharp.D2D1.WinUI.SourceGenerators;
using ComputeSharp.Tests.SourceGenerators.Helpers;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ComputeSharp.D2D1.WinUI.Tests.SourceGenerators;

[TestClass]
public class Test_CanvasEffectPropertyGenerator
{
    [TestMethod]
    public void SingleProperty()
    {
        const string source = """
            using ComputeSharp.D2D1.WinUI;

            namespace MyNamespace;

            public abstract partial class MyEffect : CanvasEffect
            {
                [GeneratedCanvasEffectProperty]
                public partial int Number { get; set; }
            }
            """;

        const string result = """"
            // <auto-generated/>
            #pragma warning disable

            namespace MyNamespace
            {
                /// <inheritdoc cref="MyEffect"/>
                partial class MyEffect
                {
                    /// <inheritdoc/>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    [global::System.Diagnostics.DebuggerNonUserCode]
                    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
                    public partial int Number
                    {
                        get => field;
                        set
                        {
                            if (global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(field, value))
                            {
                                return;
                            }

                            int oldValue = field;

                            OnNumberChanging(value);
                            OnNumberChanging(oldValue, value);

                            field = value;

                            OnNumberChanged(value);
                            OnNumberChanged(oldValue, value);

                            InvalidateEffectGraph(global::ComputeSharp.D2D1.WinUI.CanvasEffectInvalidationType.Update);
                        }
                    }

                    /// <summary>Executes the logic for when <see cref="Number"/> is changing.</summary>
                    /// <param name="value">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanging(int newValue);

                    /// <summary>Executes the logic for when <see cref="Number"/> is changing.</summary>
                    /// <param name="oldValue">The previous property value that is being replaced.</param>
                    /// <param name="newValue">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanging(int oldValue, int newValue);

                    /// <summary>Executes the logic for when <see cref="Number"/> has just changed.</summary>
                    /// <param name="value">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanged(int newValue);

                    /// <summary>Executes the logic for when <see cref="Number"/> has just changed.</summary>
                    /// <param name="oldValue">The previous property value that has been replaced.</param>
                    /// <param name="newValue">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanged(int oldValue, int newValue);
                }
            }
            """";

        VerifyGeneratedDiagnostics(source, ("MyNamespace.MyEffect.g.cs", result));
    }

    [TestMethod]
    public void SingleProperty_WithNullabilityAnnotations()
    {
        const string source = """
            using ComputeSharp.D2D1.WinUI;

            namespace MyNamespace;

            public abstract partial class MyEffect : CanvasEffect
            {
                [GeneratedCanvasEffectProperty]
                public partial object? Instance { get; set; }
            }
            """;

        const string result = """"
            // <auto-generated/>
            #pragma warning disable

            namespace MyNamespace
            {
                /// <inheritdoc cref="MyEffect"/>
                partial class MyEffect
                {
                    /// <inheritdoc/>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    [global::System.Diagnostics.DebuggerNonUserCode]
                    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
                    public partial object? Instance
                    {
                        get => field;
                        set
                        {
                            if (global::System.Collections.Generic.EqualityComparer<object?>.Default.Equals(field, value))
                            {
                                return;
                            }

                            object? oldValue = field;

                            OnInstanceChanging(value);
                            OnInstanceChanging(oldValue, value);

                            field = value;

                            OnInstanceChanged(value);
                            OnInstanceChanged(oldValue, value);

                            InvalidateEffectGraph(global::ComputeSharp.D2D1.WinUI.CanvasEffectInvalidationType.Update);
                        }
                    }

                    /// <summary>Executes the logic for when <see cref="Instance"/> is changing.</summary>
                    /// <param name="value">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Instance"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnInstanceChanging(object? newValue);

                    /// <summary>Executes the logic for when <see cref="Instance"/> is changing.</summary>
                    /// <param name="oldValue">The previous property value that is being replaced.</param>
                    /// <param name="newValue">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Instance"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnInstanceChanging(object? oldValue, object? newValue);

                    /// <summary>Executes the logic for when <see cref="Instance"/> has just changed.</summary>
                    /// <param name="value">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Instance"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnInstanceChanged(object? newValue);

                    /// <summary>Executes the logic for when <see cref="Instance"/> has just changed.</summary>
                    /// <param name="oldValue">The previous property value that has been replaced.</param>
                    /// <param name="newValue">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Instance"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnInstanceChanged(object? oldValue, object? newValue);
                }
            }
            """";

        VerifyGeneratedDiagnostics(source, ("MyNamespace.MyEffect.g.cs", result));
    }

    [TestMethod]
    public void SingleProperty_WithNotNullableReferenceType()
    {
        const string source = """
            using ComputeSharp.D2D1.WinUI;

            namespace MyNamespace;

            public abstract partial class MyEffect : CanvasEffect
            {
                [GeneratedCanvasEffectProperty]
                public partial object Instance { get; set; }
            }
            """;

        const string result = """"
            // <auto-generated/>
            #pragma warning disable

            namespace MyNamespace
            {
                /// <inheritdoc cref="MyEffect"/>
                partial class MyEffect
                {
                    /// <inheritdoc/>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    [global::System.Diagnostics.DebuggerNonUserCode]
                    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
                    public partial object Instance
                    {
                        get => field;
                        set
                        {
                            if (global::System.Collections.Generic.EqualityComparer<object?>.Default.Equals(field, value))
                            {
                                return;
                            }

                            object? oldValue = field;

                            OnInstanceChanging(value);
                            OnInstanceChanging(oldValue, value);

                            field = value;

                            OnInstanceChanged(value);
                            OnInstanceChanged(oldValue, value);

                            InvalidateEffectGraph(global::ComputeSharp.D2D1.WinUI.CanvasEffectInvalidationType.Update);
                        }
                    }

                    /// <summary>Executes the logic for when <see cref="Instance"/> is changing.</summary>
                    /// <param name="value">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Instance"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnInstanceChanging(object newValue);

                    /// <summary>Executes the logic for when <see cref="Instance"/> is changing.</summary>
                    /// <param name="oldValue">The previous property value that is being replaced.</param>
                    /// <param name="newValue">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Instance"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnInstanceChanging(object? oldValue, object newValue);

                    /// <summary>Executes the logic for when <see cref="Instance"/> has just changed.</summary>
                    /// <param name="value">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Instance"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnInstanceChanged(object newValue);

                    /// <summary>Executes the logic for when <see cref="Instance"/> has just changed.</summary>
                    /// <param name="oldValue">The previous property value that has been replaced.</param>
                    /// <param name="newValue">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Instance"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnInstanceChanged(object? oldValue, object newValue);
                }
            }
            """";

        VerifyGeneratedDiagnostics(source, ("MyNamespace.MyEffect.g.cs", result));
    }

    [TestMethod]
    public void SingleProperty_WithCustomAccessorVisibility()
    {
        const string source = """
            using ComputeSharp.D2D1.WinUI;

            namespace MyNamespace;

            public abstract partial class MyEffect : CanvasEffect
            {
                [GeneratedCanvasEffectProperty]
                public partial int Number { get; private set; }
            }
            """;

        const string result = """"
            // <auto-generated/>
            #pragma warning disable

            namespace MyNamespace
            {
                /// <inheritdoc cref="MyEffect"/>
                partial class MyEffect
                {
                    /// <inheritdoc/>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    [global::System.Diagnostics.DebuggerNonUserCode]
                    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
                    public partial int Number
                    {
                        get => field;
                        private set
                        {
                            if (global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(field, value))
                            {
                                return;
                            }

                            int oldValue = field;

                            OnNumberChanging(value);
                            OnNumberChanging(oldValue, value);

                            field = value;

                            OnNumberChanged(value);
                            OnNumberChanged(oldValue, value);

                            InvalidateEffectGraph(global::ComputeSharp.D2D1.WinUI.CanvasEffectInvalidationType.Update);
                        }
                    }

                    /// <summary>Executes the logic for when <see cref="Number"/> is changing.</summary>
                    /// <param name="value">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanging(int newValue);

                    /// <summary>Executes the logic for when <see cref="Number"/> is changing.</summary>
                    /// <param name="oldValue">The previous property value that is being replaced.</param>
                    /// <param name="newValue">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanging(int oldValue, int newValue);

                    /// <summary>Executes the logic for when <see cref="Number"/> has just changed.</summary>
                    /// <param name="value">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanged(int newValue);

                    /// <summary>Executes the logic for when <see cref="Number"/> has just changed.</summary>
                    /// <param name="oldValue">The previous property value that has been replaced.</param>
                    /// <param name="newValue">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanged(int oldValue, int newValue);
                }
            }
            """";

        VerifyGeneratedDiagnostics(source, ("MyNamespace.MyEffect.g.cs", result));
    }

    [TestMethod]
    public void SingleProperty_Required()
    {
        const string source = """
            using ComputeSharp.D2D1.WinUI;

            namespace MyNamespace;

            public abstract partial class MyEffect : CanvasEffect
            {
                [GeneratedCanvasEffectProperty]
                public required partial int Number { get; set; }
            }
            """;

        const string result = """"
            // <auto-generated/>
            #pragma warning disable

            namespace MyNamespace
            {
                /// <inheritdoc cref="MyEffect"/>
                partial class MyEffect
                {
                    /// <inheritdoc/>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    [global::System.Diagnostics.DebuggerNonUserCode]
                    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
                    public required partial int Number
                    {
                        get => field;
                        set
                        {
                            if (global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(field, value))
                            {
                                return;
                            }

                            int oldValue = field;

                            OnNumberChanging(value);
                            OnNumberChanging(oldValue, value);

                            field = value;

                            OnNumberChanged(value);
                            OnNumberChanged(oldValue, value);

                            InvalidateEffectGraph(global::ComputeSharp.D2D1.WinUI.CanvasEffectInvalidationType.Update);
                        }
                    }

                    /// <summary>Executes the logic for when <see cref="Number"/> is changing.</summary>
                    /// <param name="value">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanging(int newValue);

                    /// <summary>Executes the logic for when <see cref="Number"/> is changing.</summary>
                    /// <param name="oldValue">The previous property value that is being replaced.</param>
                    /// <param name="newValue">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanging(int oldValue, int newValue);

                    /// <summary>Executes the logic for when <see cref="Number"/> has just changed.</summary>
                    /// <param name="value">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanged(int newValue);

                    /// <summary>Executes the logic for when <see cref="Number"/> has just changed.</summary>
                    /// <param name="oldValue">The previous property value that has been replaced.</param>
                    /// <param name="newValue">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Number"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnNumberChanged(int oldValue, int newValue);
                }
            }
            """";

        VerifyGeneratedDiagnostics(source, ("MyNamespace.MyEffect.g.cs", result));
    }

    [TestMethod]
    public void MultipleProperties()
    {
        const string source = """
            using ComputeSharp.D2D1.WinUI;

            namespace MyNamespace;

            public abstract partial class MyEffect : CanvasEffect
            {
                [GeneratedCanvasEffectProperty]
                public partial int X { get; set; }

                [GeneratedCanvasEffectProperty(CanvasEffectInvalidationType.Creation)]
                public partial int Y { get; set; }
            }
            """;

        const string result = """"
            // <auto-generated/>
            #pragma warning disable

            namespace MyNamespace
            {
                /// <inheritdoc cref="MyEffect"/>
                partial class MyEffect
                {
                    /// <inheritdoc/>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    [global::System.Diagnostics.DebuggerNonUserCode]
                    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
                    public partial int X
                    {
                        get => field;
                        set
                        {
                            if (global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(field, value))
                            {
                                return;
                            }

                            int oldValue = field;

                            OnXChanging(value);
                            OnXChanging(oldValue, value);

                            field = value;

                            OnXChanged(value);
                            OnXChanged(oldValue, value);

                            InvalidateEffectGraph(global::ComputeSharp.D2D1.WinUI.CanvasEffectInvalidationType.Update);
                        }
                    }

                    /// <inheritdoc/>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    [global::System.Diagnostics.DebuggerNonUserCode]
                    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
                    public partial int Y
                    {
                        get => field;
                        set
                        {
                            if (global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(field, value))
                            {
                                return;
                            }

                            int oldValue = field;

                            OnYChanging(value);
                            OnYChanging(oldValue, value);

                            field = value;

                            OnYChanged(value);
                            OnYChanged(oldValue, value);

                            InvalidateEffectGraph(global::ComputeSharp.D2D1.WinUI.CanvasEffectInvalidationType.Creation);
                        }
                    }

                    /// <summary>Executes the logic for when <see cref="X"/> is changing.</summary>
                    /// <param name="value">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="X"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnXChanging(int newValue);

                    /// <summary>Executes the logic for when <see cref="X"/> is changing.</summary>
                    /// <param name="oldValue">The previous property value that is being replaced.</param>
                    /// <param name="newValue">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="X"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnXChanging(int oldValue, int newValue);

                    /// <summary>Executes the logic for when <see cref="X"/> has just changed.</summary>
                    /// <param name="value">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="X"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnXChanged(int newValue);

                    /// <summary>Executes the logic for when <see cref="X"/> has just changed.</summary>
                    /// <param name="oldValue">The previous property value that has been replaced.</param>
                    /// <param name="newValue">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="X"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnXChanged(int oldValue, int newValue);

                    /// <summary>Executes the logic for when <see cref="Y"/> is changing.</summary>
                    /// <param name="value">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Y"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnYChanging(int newValue);

                    /// <summary>Executes the logic for when <see cref="Y"/> is changing.</summary>
                    /// <param name="oldValue">The previous property value that is being replaced.</param>
                    /// <param name="newValue">The new property value being set.</param>
                    /// <remarks>This method is invoked right before the value of <see cref="Y"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnYChanging(int oldValue, int newValue);

                    /// <summary>Executes the logic for when <see cref="Y"/> has just changed.</summary>
                    /// <param name="value">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Y"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnYChanged(int newValue);

                    /// <summary>Executes the logic for when <see cref="Y"/> has just changed.</summary>
                    /// <param name="oldValue">The previous property value that has been replaced.</param>
                    /// <param name="newValue">The new property value that has been set.</param>
                    /// <remarks>This method is invoked right after the value of <see cref="Y"/> is changed.</remarks>
                    [global::System.CodeDom.Compiler.GeneratedCode("ComputeSharp.D2D1.WinUI.CanvasEffectPropertyGenerator", <ASSEMBLY_VERSION>)]
                    partial void OnYChanged(int oldValue, int newValue);
                }
            }
            """";

        VerifyGeneratedDiagnostics(source, ("MyNamespace.MyEffect.g.cs", result));
    }

    /// <summary>
    /// Verifies the output of a source generator.
    /// </summary>
    /// <param name="source">The input source to process.</param>
    /// <param name="result">The expected source to be generated.</param>
    /// <returns>The task for the operation.</returns>
    private static void VerifyGeneratedDiagnostics(string source, (string Filename, string Source) result)
    {
        // We cannot run the analyzers on the input source, because they'd report unwanted dsiagnostics due to the
        // partial properties missing an implementation part. For this generator, we just test analyzers individually.
        CSharpGeneratorTest<CanvasEffectPropertyGenerator>.VerifySources(source, result, languageVersion: LanguageVersion.Preview);
    }
}